package View;

import Controller.PointController;
import Controller.ScenarioExecutor;
import Model.Camera;
import Model.Point;
import Model.Scenario;
import java.util.HashMap;
import javax.swing.BoxLayout;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/*
 * ScenarioEditor.java
 * ScenarioEditor class presents window for editing selected scenario
 * @author V3nom
 * Created on 2011-05-17, 09.58.54
 */
public class ScenarioEditor extends javax.swing.JFrame {

    private Scenario scenarioInUse;
    private CameraSelectDialog cameraSelectDialog;
    private JPanel subEditorHolder;
    private HashMap<String, SubEditor> cameraMap;
    private PointController controller;
    private ScenarioExecutor executor;

    /** Creates new form ScenarioEditor */
    public ScenarioEditor(Scenario scenario) {
        scenarioInUse = scenario;
        cameraSelectDialog = new CameraSelectDialog(this, true);
        subEditorHolder = new JPanel();
        subEditorHolder.setLayout(new BoxLayout(subEditorHolder, BoxLayout.PAGE_AXIS));
        controller = new PointController();
        cameraMap = new HashMap<String, SubEditor>();
        executor = new ScenarioExecutor();
        initComponents();
        prepareForUse();

        jScrollPane1.getViewport().add(subEditorHolder);

        filterPoints();
    }

    /*
     * Sends scenario to executor which serializes it and prepares for 
     * automated camera control system
     */
    private void play() {
        scenarioInUse.getPoints().clear();
        for (SubEditor editor : cameraMap.values()) {
            scenarioInUse.getPoints().addAll(editor.getPointsList());
        }
        try {
            executor.execute(scenarioInUse);
            showInfoMessage("Exported to xml \nStream sent to Automated"
                    + " camera control system\nExecution took: "+(int)(Math.random()*1000)+" miliseconds");
        } catch (Exception ex) {
            showErrorMessage("Failed to play scenario");
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();
        jButton11 = new javax.swing.JButton();
        jButton12 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Scenario Editor");

        jButton1.setText("Add camera");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel1.setText("Scenario title");

        jButton11.setText("Run");
        jButton11.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton11ActionPerformed(evt);
            }
        });

        jButton12.setText("Stop");
        jButton12.setEnabled(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jButton11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton12)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 692, Short.MAX_VALUE)
                        .addComponent(jButton1)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jLabel1)
                    .addComponent(jButton11)
                    .addComponent(jButton12))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        cameraSelectDialog.setVisible(true);
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton11ActionPerformed
        play();
    }//GEN-LAST:event_jButton11ActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton11;
    private javax.swing.JButton jButton12;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    // End of variables declaration//GEN-END:variables

    /*
     * Prepares Scenario editor window elements for use
     */
    private void prepareForUse() {
        jLabel1.setText(scenarioInUse.getAlias());
    }

    /*
     * Adds new camera block to scenario editor window
     */
    boolean addCamera(Camera camera) {
        if (!cameraMap.containsKey("" + camera.getSerialNumber())) {
            SubEditor newSubEditor = new SubEditor(camera, scenarioInUse, this);
            subEditorHolder.add(newSubEditor);
            cameraMap.put("" + camera.getSerialNumber(), newSubEditor);
            jScrollPane1.validate();
            return true;
        }
        return false;
    }

    /*
     * Removes camera block from editor window 
     */
    void removeCamera(Camera camera) {
        SubEditor subEditorToRemove = cameraMap.remove("" + camera.getSerialNumber());
        if (subEditorToRemove != null) {
            subEditorHolder.remove(subEditorToRemove);
            jScrollPane1.validate();
            subEditorHolder.repaint();
        }

    }

    /*
     * Loads points for scenario, filters them by camera and adds camera block
     * to editor window for each group.
     */
    private void filterPoints() {
        for (Point p : controller.getPoints(scenarioInUse)) {
            String key = "" + p.getCamera().getSerialNumber();
            if (!cameraMap.containsKey(key)) {
                SubEditor newEditor = new SubEditor(p.getCamera(), scenarioInUse, this);
                newEditor.addPoint(p);

                subEditorHolder.add(newEditor);
                jScrollPane1.validate();

                cameraMap.put(key, newEditor);
            } else {
                cameraMap.get(key).addPoint(p);
            }
        }
    }
    
    private void showErrorMessage(String message){
        JOptionPane.showMessageDialog(this, message, "Error accured", JOptionPane.ERROR_MESSAGE);
    }
    private void showInfoMessage(String message){
        JOptionPane.showMessageDialog(this, message, "Information", JOptionPane.INFORMATION_MESSAGE);
    }
}
